//
//  TestCaptureSessionViewController.swift
//  DouYuZB
//
//  Created by 中创 on 2020/4/26.
//  Copyright © 2020 梁森. All rights reserved.
//

import UIKit

import AVFoundation

class TestCaptureSessionViewController: UIViewController {

    fileprivate lazy var videoQueue:DispatchQueue = DispatchQueue.global()
    fileprivate lazy var audioQueue:DispatchQueue = DispatchQueue.global()
    fileprivate lazy var captureSession:AVCaptureSession = AVCaptureSession()
    fileprivate lazy var previewLayer:AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
//    fileprivate var connection:AVCaptureConnection?
    fileprivate var videoInput:AVCaptureDeviceInput?
    fileprivate var videoOutput:AVCaptureVideoDataOutput?
    fileprivate var movieOutput:AVCaptureMovieFileOutput?
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

   
    
    
}
extension TestCaptureSessionViewController{
    
    @IBAction func startCapture(_ sender: Any) {
        
        setupVideo()
        setupAudio()
        
        // 添加写入文件的output
        let movieOutput = AVCaptureMovieFileOutput()
        captureSession.addOutput(movieOutput)
        // 设置写入的稳定性
        let connection = movieOutput.connection(with: AVMediaType.video)
        connection?.preferredVideoStabilizationMode = .auto
        self.movieOutput = movieOutput
        
        // 添加预览视图
        previewLayer.frame = view.bounds
        view.layer.insertSublayer(previewLayer, at: 0)
        captureSession.startRunning()
        
        // 将采集到的画面写入文件
        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "abc.mp4"
        let url = URL(fileURLWithPath: path)
        movieOutput.startRecording(to: url, recordingDelegate: self)
    }
    
    @IBAction func stopCapture(_ sender: Any) {
        movieOutput?.stopRecording()
        captureSession.stopRunning()
        previewLayer.removeFromSuperlayer()
    }
    // 切换摄像头
    @IBAction func switchScene(_ sender: Any) {
        guard var position = self.videoInput?.device.position else {return}
        position = position == AVCaptureDevice.Position.front ? AVCaptureDevice.Position.back : AVCaptureDevice.Position.front
        
        guard let devices = AVCaptureDevice.devices(for: AVMediaType.video) as? [AVCaptureDevice] else{
            print("摄像头不可用...")
            return
        }
        guard let device = devices.filter({$0.position == position}).first else {return}
        guard let videoInput = try? AVCaptureDeviceInput(device: device) else {return}
        // 切换
        captureSession.beginConfiguration()
        captureSession.removeInput(self.videoInput!)
        captureSession.addInput(videoInput)
        captureSession.commitConfiguration()
        self.videoInput = videoInput
    }
    
    /// 采集视频数据
    private func setupVideo(){
        // 获取摄像头设备
        guard let devices = AVCaptureDevice.devices(for: AVMediaType.video) as? [AVCaptureDevice] else{
            print("摄像头不可用...")
            return
        }
        guard let device = devices.filter({$0.position == .front}).first else {return}
        guard let videoInput = try? AVCaptureDeviceInput(device: device) else {return}
        self.videoInput = videoInput
        captureSession.addInput(videoInput)
        let videoOutput = AVCaptureVideoDataOutput()
        videoOutput.setSampleBufferDelegate(self as AVCaptureVideoDataOutputSampleBufferDelegate, queue: videoQueue)
        captureSession.addOutput(videoOutput)
        
        self.videoOutput = videoOutput
    }
    /// 采集音频数据
    private func setupAudio(){
        guard let device = AVCaptureDevice.default(for: AVMediaType.audio) else {return}
        guard let audioInput = try? AVCaptureDeviceInput(device: device) else {return}
        captureSession.addInput(audioInput)
        
        let audioOutput = AVCaptureAudioDataOutput()
        audioOutput.setSampleBufferDelegate(self as? AVCaptureAudioDataOutputSampleBufferDelegate, queue: audioQueue)
        captureSession.addOutput(audioOutput)
    }
    
}

extension TestCaptureSessionViewController:AVCaptureVideoDataOutputSampleBufferDelegate{
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        if connection == self.videoOutput?.connection(with: AVMediaType.video) {
            print("采集的是视频")
        }else{
            print("采集的是音频")
        }
        
    }
}
extension TestCaptureSessionViewController:AVCaptureFileOutputRecordingDelegate{
    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
        
    }
    
    func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {
        
    }
}
